package utils;


import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;

import org.apache.log4j.Logger;

/**
 * Application Lifecycle Listener implementation class ActiveUsersListener
 *
 */
public class UsersOnlineHttpSessionAttributeListener implements HttpSessionAttributeListener {

	private static Logger log = Logger.getLogger(UsersOnlineHttpSessionAttributeListener.class);
	//key = user_id; value = room_id
	private static Map<Integer, Integer> usersOnline = Collections.synchronizedMap(new HashMap<Integer, Integer>());
	
    /**
     * Default constructor. 
     */
    public UsersOnlineHttpSessionAttributeListener() { }

	@Override
	public void attributeAdded(HttpSessionBindingEvent arg0) {
		log.debug("atributeAdded " + arg0.getName() + " [" + arg0.getValue() + "]; class : " + arg0.getValue().getClass().getName());
		String name = arg0.getName();
		String value = arg0.getValue().toString();
		
		String currentRoomId = getSessionAttribute(arg0.getSession(), "currentRoomId");
		String currentUserId = getSessionAttribute(arg0.getSession(), "currentUserId");
		
		log.debug("Attribute added [" + name + "] old value [" + value + "] currentRoomId [" + currentRoomId + "] currentUserId [" + currentUserId + "]");
		updateActiveUsers(name, value, currentRoomId, currentUserId);
	}

	@Override
	public void attributeRemoved(HttpSessionBindingEvent arg0) {
		log.debug("attributeRemoved " + arg0.getName() + " [" + arg0.getValue() + "]; class : " + arg0.getValue().getClass().getName());
		
		String name = arg0.getName();
		String value = arg0.getValue().toString();
		
		//String currentRoomId = getSessionAttribute(arg0.getSession(), "currentRoomId");			
		
		log.debug("Attribute removed [" + name + "] old value [" + value + "]");
		removeActiveser(name, value);
	}

	@Override
	public void attributeReplaced(HttpSessionBindingEvent arg0) {
		log.debug("attributeReplaced " + arg0.getName() + " [" + arg0.getValue() + "]; class : " + arg0.getValue().getClass().getName());
		
		String name = arg0.getName();
		String value = arg0.getValue().toString();
		
		String currentRoomId = getSessionAttribute(arg0.getSession(), "currentRoomId");
		String currentUserId = getSessionAttribute(arg0.getSession(), "currentUserId");
		
		log.debug("Attribute replaced [" + name + "] old value [" + value + "] currentRoomId [" + currentRoomId + "] currentUserId [" + currentUserId + "]");
		updateActiveUsers(name, value, currentRoomId, currentUserId);
	}

	private void updateActiveUsers(String name, String value, String currentRoomId, String currentUserId) {
	
		if (value.isEmpty() || 
				currentUserId.isEmpty() || 
				currentRoomId.isEmpty()) {
			log.debug("can not update active users! Empty value.");
			return;
		}
		
		if (name.equalsIgnoreCase("currentUserId")) {
			log.debug("addin the user");
			//add new user
			usersOnline.put(Integer.valueOf(currentUserId), Integer.valueOf(currentRoomId));
			
			if (!value.equalsIgnoreCase(currentUserId)) {
				//remove old user
				usersOnline.remove(Integer.valueOf(value));				
			}			
		}
		
		if (name.equalsIgnoreCase("currentRoomId")) {
			usersOnline.put(Integer.valueOf(currentUserId), Integer.valueOf(currentRoomId));
		}
		log.debug("getUsersOnline size " + usersOnline.size());
		log.debug("users online " + usersOnline.toString());
		
	}
	
	private void removeActiveser(String name, String value) {
	
		if ( value.isEmpty() ) {
			log.debug("can not remove active user! Empty value.");
			return;
		}
		
		if (name.equalsIgnoreCase("currentUserId")) {
			usersOnline.remove(Integer.valueOf(value));
		}
		log.debug("users online " + usersOnline.toString());
	}
	
	private String getSessionAttribute(HttpSession session, String sessionAttributeName) {		
		String value = "";
		
		Object obj = session.getAttribute(sessionAttributeName);
		if (obj != null) value = obj.toString();
		
		return value;
	}
	
	public static Map<Integer, Integer> getActiveUsers() {
		return usersOnline;
	}
	
}
